#pragma once
#include <iostream>
#include <cstring>
#include <string>
#include <list>
#define CRLF_LEN (strlen(CRLF))
#define SPACE " "
#define SPACE_LEN (strlen(" "))
const char *SEP = "\n";
const size_t SEP_LEN = strlen(SEP);
// 协议定制 序列化/反序列化 与业务也网络解耦
//  xxxxxx\3xxxx\3xxxxxx\3
void package_split(std::string &buffer, std::list<std::string> &result)
{
    while (true)
    {
        size_t pos = buffer.find(SEP);
        if (pos == 0)
        {
            buffer.erase(0, pos + SEP_LEN);
            continue;
        }
        if (pos == std::string::npos)
        {
            break;
        }
        result.push_back(buffer.substr(0, pos));
        buffer.erase(0, pos + SEP_LEN);
    }
}
struct request
{
    // serialize struct -> string
    // a + b
    std::string serialize()
    {
        return std::to_string(_a) + SPACE + _op + SPACE + std::to_string(_b);
    }
    // deserialize string -> struct
    // a + b
    void deserialize(const std::string &str)
    {

        int space_pos = str.find(SPACE);
        _a = stoi(str.substr(0, space_pos));
        _op = str[space_pos + SPACE_LEN];
        _b = stoi(str.substr(space_pos + 2 * SPACE_LEN + 1));
    }
    int _a;
    int _b;
    char _op;
};
// 1+1or 1+   -1or1        ++1
std::pair<bool, request> make_request(const std::string &str)
{
    int pos = -1;
    // traversal
    for (int i = 1; i < str.size(); i++)
    {
        if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' || str[i] == '%')
        {
            if (i + 1 < str.size() && !(str[i + 1] == '+' || str[i + 1] == '-'))
            {
                pos = i;
                break;
            }
        }
    }
    request req;
    if (pos == -1)
    {
        return {false, req};
    }
    req._a = stoi(str.substr(0, pos));
    req._op = str[pos];
    req._b = stoi(str.substr(pos + 1));
    return {true, req};
}
struct response
{
    //  struct -> string
    std::string serialize()
    {
        return std::to_string(_exit_code) + SPACE + std::to_string(_result);
    }
    // string -> struct
    void deserialize(const std::string &str)
    {

        int pos = str.find(SPACE);
        _exit_code = std::stoi(str.substr(0, pos));
        _result = stoi(str.substr(pos + 1));
    }
    int _exit_code;
    int _result;
};
